/*
 * Copyright (C) 2009 University of Washington
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package org.opendatakit.collect.android.tasks;

import java.io.File;
import java.util.UUID;

import org.opendatakit.collect.android.application.Collect;
import org.opendatakit.collect.android.listeners.FormLoaderListener;
import org.opendatakit.collect.android.logic.FormController;
import org.opendatakit.collect.android.provider.InstanceProviderAPI.InstanceColumns;
import org.opendatakit.collect.android.utilities.FileUtils;

import android.database.Cursor;
import android.os.AsyncTask;

/**
 * Background task for loading a form.
 * 
 * @author Carl Hartung (carlhartung@gmail.com)
 * @author Yaw Anokwa (yanokwa@gmail.com)
 */
public class FormLoaderTask extends AsyncTask<String, String, Void> {
    @SuppressWarnings("unused")
	private final static String t = "FormLoaderTask";

    private FormLoaderListener mStateListener;
    private String mErrorMsg = null;
    private FormController mFc = null;
    /**
     * Initialize {@link FormEntryController} with {@link FormDef} from binary or from XML. If given
     * an instance, it will be used to fill the {@link FormDef}.
     */
    @Override
    protected Void doInBackground(String... path) {
        mErrorMsg = null;
        mFc = null;

        String formPath = path[0];

        File formXml = new File(formPath);
        
        if (mErrorMsg != null) {
            return null;
        }
        
        String instanceId = "uuid:" + UUID.randomUUID().toString();

        try {
            // import existing data into formdef
            if (Collect.mInstancePath != null) {
                // This order is important. Import data, then initialize.
            	instanceId = importData(Collect.mInstancePath);
            }
        } catch (RuntimeException e) {
            mErrorMsg = e.getMessage();
            return null;
        }

        // set paths to /sdcard/odk/forms/formfilename-media/
        String formFileName = formXml.getName().substring(0, formXml.getName().lastIndexOf("."));

        // clean up vars
        formXml = null;
        formPath = null;

        FormController fc = new FormController(new File(Collect.FORMS_PATH, formFileName + "-media"), instanceId);
        mFc = fc;
        return null;
    }


    private String importData(String filePath) {
    	
    	File f = new File(filePath);
    	if ( f.exists() ) {
    		// convert files into a byte array
    		byte[] fileBytes = FileUtils.getFileAsBytes(new File(filePath));
    		// TODO: parse this for the instanceID?
    	}

    	String where = InstanceColumns.INSTANCE_FILE_PATH + "=?";
        String[] whereArgs = {
        		filePath
        };
        
        Cursor c = null;
        try {
        	c = Collect.getInstance().getContentResolver()
                    .query(InstanceColumns.CONTENT_URI, null, where, whereArgs, null);
        	
        	if ( c.getCount() != 1 ) {
        		throw new IllegalStateException("Could not find any record of this filled-in form: " + filePath);
        	}
        	c.moveToFirst();

        	// TODO: confirm that this instance has the same form id, etc. as the 
        	// form definition file.
            // TODO: reload instance data from filePath file.
            // TODO: confirm that instance data is for the same formId and version as one we have?
            // TODO: return the instanceId from this file
        	
        	String instanceId = c.getString(c.getColumnIndex(InstanceColumns.INSTANCE_ID));
        	if ( instanceId == null || instanceId.length() == 0 ) {
        		throw new IllegalStateException("Null or empty valued instance id for: " + filePath);
        	}
        	
        	return instanceId;
        } finally {
        	if ( c != null ) {
        		c.close();
        	}
        }
    }


    @Override
    protected void onPostExecute(Void v) {
        synchronized (this) {
            if (mStateListener != null) {
                if (mFc == null) {
                    mStateListener.loadingError(mErrorMsg);
                } else {
                    mStateListener.loadingComplete(mFc);
                }
            }
        }
    }


    public void setFormLoaderListener(FormLoaderListener sl) {
        synchronized (this) {
            mStateListener = sl;
        }
    }

    public String getErrorMsg() {
    	return mErrorMsg;
    }
    
    public FormController getFormController() {
    	return mFc;
    }

}
